#include "dauproxyapi.h"
#include <dlfcn.h>
#include "errno_sdk.h"

#define CHECK_DLERROR(errCode)  \
    do {                  \
        char *e = dlerror();                  \
        if ((e) != nullptr) { \
            printf("dl error: %s\n", (e)); \
            return (errCode);                  \
        }   \
    } while(0)  \


DauProxyApi::DauProxyApi()
{
    pHandle = nullptr;
}

DauProxyApi::~DauProxyApi()
{
    if (pHandle != nullptr)
    {
        printf("Execute ~DauProxyApi\n");
        dlclose(pHandle);
    }
}

DauProxyApi* DauProxyApi::GetInstance()
{
    static DauProxyApi g_dayProxyApi;
    return &g_dayProxyApi;
}

#define SET_FUNC(handle, pFunc, funcDef, name) \
    do {                                       \
             (pFunc) = (funcDef)dlsym((handle), (name)); \
             CHECK_DLERROR(ERR_LIB_DAUPROXY_NO_FUNC);    \
    }while(0)

int DauProxyApi::Init()
{


    char *libProxyPath = getenv("LIB_PROXY_PATH");
    if (libProxyPath == nullptr || strlen(libProxyPath) == 0)
    {
        return ERR_LIB_PROXY_PATH;
    }

    string soFilePath = string(libProxyPath);
    if (soFilePath.back() != '/')
    {
        soFilePath.append("/");
    }
    soFilePath.append("libdauproxyplus.so");

    if (pHandle == nullptr)
    {
        pHandle = dlopen(soFilePath.c_str(), RTLD_LAZY | RTLD_LOCAL);
        CHECK_DLERROR(ERR_LIB_DAUPROXY);
    }

    SET_FUNC(pHandle, ProxySetLibraryPath, dauproxy_api_func::ProxySetLibraryPath, "Proxy_SetLibraryPath");
    int code = ProxySetLibraryPath(libProxyPath);
    if (code < 0)
    {
        return ERR_CALL_PROXY_SETLIBRARYPATH;
    }

    SET_FUNC(pHandle, ProxyInitLibrary, dauproxy_api_func::ProxyInitLibrary, "Proxy_InitLibrary");
    code = ProxyInitLibrary();
    if (code < 0)
    {
        return ERR_CALL_PROXY_INITLIBRARY;
    }

    SET_FUNC(pHandle, ProxyReleaseLibrary, dauproxy_api_func::ProxyReleaseLibrary, "Proxy_ReleaseLibrary");
    SET_FUNC(pHandle, ProxyAddDevice, dauproxy_api_func::ProxyAddDevice, "Proxy_AddDevice");
    SET_FUNC(pHandle, ProxyAddDevicePlus, dauproxy_api_func::ProxyAddDevicePlus, "Proxy_AddDevicePlus");
    SET_FUNC(pHandle, ProxyLogin, dauproxy_api_func::ProxyLogin, "Proxy_Login");
    SET_FUNC(pHandle, ProxyLogout, dauproxy_api_func::ProxyLogout, "Proxy_Logout");
    SET_FUNC(pHandle, ProxyGetDeviceState, dauproxy_api_func::ProxyGetDeviceState, "Proxy_GetDeviceState");
    SET_FUNC(pHandle, ProxyDeleteDevice, dauproxy_api_func::ProxyDeleteDevice, "Proxy_DeleteDevice");

    SET_FUNC(pHandle, ProxyGetDeviceInfo, dauproxy_api_func::ProxyGetDeviceInfo, "Proxy_GetDeviceInfo");
    SET_FUNC(pHandle, ProxyGetDevChannelInfo, dauproxy_api_func::ProxyGetDevChannelInfo, "Proxy_GetDevChannelInfo");
    SET_FUNC(pHandle, ProxyPtzControl, dauproxy_api_func::ProxyPtzControl, "Proxy_PtzControl");

    SET_FUNC(pHandle, ProxyGetVodStreamUrl, dauproxy_api_func::ProxyGetVodStreamUrl, "Proxy_GetVodStreamUrl");
    SET_FUNC(pHandle, ProxyGetLiveStreamUrl, dauproxy_api_func::ProxyGetLiveStreamUrl, "Proxy_GetLiveStreamUrl");
    return 0;
}

